import services from '@/services/nginx';
import messageServices from '@/services/message';
import sshServices from '@/services/ssh';
import {ActionType, PageContainer, ProColumns, ProTable,} from '@ant-design/pro-components';
import {Button, Dropdown, message, Modal, Tooltip} from 'antd';
import React, {useEffect, useRef, useState} from 'react';
import CreateForm from './components/CreateForm';
import SettingWebhook, {FormValueType} from './components/SettingWebhook';
import {DownOutlined} from '@ant-design/icons';
import SettingAccess from './components/SettingAccess';
import {apiPrefixDispose} from '@/utils/format';
import SettingSSH from './components/SettingSSH';
import SettingSslPath from './components/SettingSslPath';
import {ItemType} from 'antd/es/menu/interface';

const {registerDomain,pageDomain,sslVerify, buildSsl,ssh, settingSslPath,deleteDomain, webhook,access, webhookNotification} = services.NginxSslController;


type WebhookEnumData = {
    [key: string]: { text: string; status: number };
  };

/**
 * 注册需要监控的域名
 * @param fields
 */
const handleRegisterDomain = async (fields: API.DomainRegister) => {
    const hide = message.loading('正在添加');
    if (!fields) return true;
    try {
        console.log("注册需要监控的域名",fields)
        await registerDomain({...fields});
        hide();
        message.success('添加成功');
        return true;
    } catch (error) {
        hide();
        // message.error('添加失败请重试！');
        return false;
    }
};

/**
 *  删除域名
 * @param codes
 */
const handleRemoveDomain = async (id: number) => {
    const hide = message.loading('正在删除');
    if (!id) return true;
    try {
        await deleteDomain(id);
        hide();
        message.success('删除成功');
        return true;
    } catch (error) {
        hide();
        // message.error('删除失败，请重试');
        return false;
    }
};

/**
 *  验证域名
 * @param codes
 */
const handleSslVerify = async (domain: string) => {
    const hide = message.loading('正在验证');
    if (!domain) return true;
    try {
       const response =  await sslVerify(domain);
        hide();
        message.success(response.message);
        return true;
    } catch (error) {
        hide();
        // message.error('验证失败，请重试');
        return false;
    }
};

/**
 *  域名设置webhook
 */
const handleWebhook = async (fields: FormValueType) => {
    const hide = message.loading('正在设置webhook');
    if (!fields) return true;
    try {
        await webhook({ ...fields, id: fields.id as number });
        hide();
        message.success('设置webhook成功');
        return true;
    } catch (error) {
        hide();
        // message.error('设置webhook失败，请重试');
        return false;
    }
};


/**
 *  域名设置access
 */
const handleAccess = async (fields: FormValueType) => {
    const hide = message.loading('正在设置access');
    if (!fields) return true;
    try {
        await access({ ...fields, id: fields.id as number });
        hide();
        message.success('设置access成功');
        return true;
    } catch (error) {
        hide();
        // message.error('设置webhook失败，请重试');
        return false;
    }
};

/**
 *  域名设置ssh
 */
const handleSsh = async (fields: FormValueType) => {
    const hide = message.loading('正在设置ssh');
    if (!fields) return true;
    try {
        await ssh({ ...fields, id: fields.id as number });
        hide();
        message.success('设置ssh成功');
        return true;
    } catch (error) {
        hide();
        // message.error('设置webhook失败，请重试');
        return false;
    }
};

/**
 *  域名设置sslpath
 */
const handleSslPath = async (fields: FormValueType) => {
    const hide = message.loading('正在设置sslPath');
    if (!fields) return true;
    try {
        await settingSslPath({ ...fields, id: fields.id as number });
        hide();
        message.success('设置sslPath成功');
        return true;
    } catch (error) {
        hide();
        // message.error('设置webhook失败，请重试');
        return false;
    }
};


const TableList: React.FC<unknown> = () => {
    const [createModalVisible, handleModalVisible] = useState<boolean>(false);
    const [stepFormValues, setStepFormValues] = useState({});
    const [accessFormValues, setAccessFormValues] = useState({});
    const [sshFormValues, setSSHFormValues] = useState({});
    const [sslPathFormValues, setSslPathFormValues] = useState({});
    const [webhookModalVisible, handleWebhookModalVisible] = useState<boolean>(false);
    const [accessModalVisible, handleAccessModalVisible] = useState<boolean>(false);
    const [sshModalVisible, handleSSHModalVisible] = useState<boolean>(false);
    const [sslPathModalVisible, handleSslPathModalVisible] = useState<boolean>(false);
    const actionRef = useRef<ActionType>();
    const [current, setCurrent] = useState(1); // 当前页码
    const [pageSize, setPageSize] = useState(10); // 每页显示条数

    const [accessKeysEnumData, setAccessKeysEnumData] = useState({});
    const [webhooksEnumData, setWebhooksEnumData] = useState<WebhookEnumData>({});
    const [sshEnumData, setSshEnumData] = useState({});


  // 初始化
  useEffect(() => {
    fetchAccessKeys();
    fetchWebhooks();
    fetchSSHs();
  }, []);


  /**
   * 获取accessKeys数据
   */
  async function fetchAccessKeys() {
    const response = await services.CloudAccessKeyController.accessKeys();
    if (response && Array.isArray(response.data)) {
      const dictData = response.data;
      const valueEnumMap: Record<string, { text: string; status: string }> = {};
      dictData.reduce((acc , item ) => {
        acc[item.accessId] =  { text: item.name , status: item.accessId };
        return acc;
      }, valueEnumMap);
      setAccessKeysEnumData(valueEnumMap);
    }
  }

  /**
   * 获取SSH数据
   */
  async function fetchSSHs() {

    const response = await sshServices.SshInfoController.listSSH();
    if (response && Array.isArray(response.data)) {
      const dictData = response.data;
      const valueEnumMap: Record<string, { text: string; status: number }> = {};
      dictData.reduce((acc , item ) => {
        acc[item.id] =  { text: item.name , status: item.id };
        return acc;
      }, valueEnumMap);
      setSshEnumData(valueEnumMap);
    }
  }

  /**
   * 获取Webhook数据
   */
  async function fetchWebhooks() {

    const response = await messageServices.WebHookController.lists();
    if (response && Array.isArray(response.data)) {
      const dictData = response.data;
      const valueEnumMap: WebhookEnumData = {};
      dictData.reduce((acc , item ) => {
        acc[item.id] =  { text: item.name , status: item.id };
        return acc;
      }, valueEnumMap);
      setWebhooksEnumData(valueEnumMap);
    }
  }

    const columns: ProColumns<API.Domains>[] = [
        {
            title: 'id',
            dataIndex: 'id',
            tooltip: '唯一的 key',
            hideInForm: true,
            hideInTable: true,
            search: false
        },
        {
            title: '域名',
            dataIndex: 'domain',
            tooltip: '唯一的key',
            copyable: true, // 启用可复制功能
            formItemProps: {
                rules: [
                    {
                        required: true,
                        message: '域名为必填项',
                    },
                ],
            },
        },
        {
            title: '剩余天数',
            dataIndex: 'expiryDay',
            tooltip: '负数为过期',
            valueType: 'digit',
            hideInForm: true,
            search: false,
            render: (text, record, index) => {
                // 判断剩余天数是否为负数
                if (record.expiryDay<=0) {
                  // 返回红色样式的文本
                  return <span style={{ color: 'red' }}>{text}</span>;
                } else {
                  return <span style={{ color: 'green' }}>{text}</span>;
                }
            },
        },
        {
            title: '证书状态',
            dataIndex: 'efficacious',
            valueType: 'text',
            hideInForm: true,
            search: false,
            valueEnum: {
                true: {text: '正常', status: 'true'},
                false: {text: '过期', status: 'false'},
            },
            render: (text, record, index) => {
                // 判断剩余天数是否为负数
                if (record.efficacious) {
                  // 返回红色样式的文本
                  return <span style={{ fontWeight: 'bold', color: 'green' }}>{text}</span>;
                } else {
                  return <span style={{ fontWeight: 'bold', color: 'red' }}>{text}</span>;
                }
            },
        },
        {
            title: '有效期结束时间',
            dataIndex: 'expiryAfter',
            valueType: 'text',
            hideInForm: true,
            search: false,
        },
        {
            title: 'Access',
            dataIndex: 'accessId',
            valueType: 'text',
            tooltip: '所属的云厂商账号的AccessId,用户申请证书的',
            valueEnum: accessKeysEnumData,
            search: false,
            copyable: true, // 启用可复制功能
        },
        {
            title: 'Webhook',
            dataIndex: 'webhookId',
            valueType: 'text',
            tooltip: '消息通知',
            hideInForm: true,
            ellipsis: true, // 启用文本省略
            search: false,
            render: (text, row) =>{
                var displayText  =  webhooksEnumData[row.webhookId] ? webhooksEnumData[row.webhookId].text : '请设置Webhook';
                // 根据displayText的值设置样式
                const style = displayText === '请设置Webhook' ? { color: 'red' } : {};
                return [
                    <a
                        target="_blank"
                        rel="noopener noreferrer"
                        key="webhook"
                        onClick={async () => {
                            handleWebhookModalVisible(true);
                            setStepFormValues(row);
                        }}
                        style={style} // 应用样式
                    >
                         <Tooltip title={displayText} >
                           {displayText }
                        </Tooltip>

                    </a>,
                ]
            },
        },
        {
            title: 'SSH',
            dataIndex: 'sshId',
            valueType: 'text',
            tooltip: '部署的服务器的SSH，用于自动更新证书的',
            valueEnum: sshEnumData,
            search: false,
            copyable: true, // 启用可复制功能
        },
        {
            title: '证书地址',
            dataIndex: 'sslPath',
            valueType: 'text',
            tooltip: '用于本地域名定时更换过期证书用的，注意文件名必须是域名.pem 和域名.key[e.g tannn.cn.pem/.key]',
            ellipsis: true, // 启用文本省略
            search: false,
            copyable: true, // 启用可复制功能
        },
        {
            title: '颁发者',
            dataIndex: 'issuer',
            valueType: 'text',
            hideInForm: true,
            search: false,
            ellipsis: true, // 启用文本省略
            formItemProps: {
                rules: [
                    {
                        required: true,
                        message: '角色为必填项',
                    },
                ],
            },
        },
        {
            title: '操作',
            dataIndex: 'option',
            valueType: 'option',
            render: (_, record) => {
              const menuItems: ItemType[] = [
                {
                  key: 'delete',
                  label:'删除',
                  onClick: () => {
                    Modal.confirm({
                      title: '确认删除',
                      content: (
                        <span>
                            确定要删除域名
                            <span style={{ fontWeight: 'bold', color: 'red' }}>
                                {record.domain}
                            </span>
                            吗？
                        </span>
                      ),
                      okText: '确认',
                      okType: 'danger',
                      cancelText: '取消',
                      onOk: async () => {
                        const success = await handleRemoveDomain(record.id);;
                        if (success) {
                            actionRef.current?.reloadAndRest?.();
                        }
                      },
                    });
                  },
                },
                {
                  key: 'handleSslVerify',
                  label: '验证',
                  onClick: async () => {
                    const resp =  await handleSslVerify(record.domain)
                    if ( resp) {
                         actionRef.current?.reloadAndRest?.();
                     }
                  },
                },
                {
                    key: 'Access',
                    label: record.accessId === null ? "Access": 'Access',
                    onClick: async () => {
                        handleAccessModalVisible(true);
                        setAccessFormValues(record);
                    },
                },
                {
                    key: 'SSH',
                    label: record.sshId === null ? "SSH": 'SSH',
                    onClick: async () => {
                        handleSSHModalVisible(true);
                        setSSHFormValues(record);
                    },
                },
                {
                    key: 'SslPath',
                    label: record.sslPath === null ? "SslPath": 'SslPath',
                    onClick: async () => {
                        handleSslPathModalVisible(true);
                        setSslPathFormValues(record);
                    },
                },

              ];
              if( record.webhookId !== null){
                menuItems.push({
                    key: 'webhookNotification',
                    label: '通知',
                    onClick: async () => {
                          const hide = message.loading('通知用户域名状态');
                          const success = await webhookNotification(record.id);;
                          if (success) {
                              actionRef.current?.reloadAndRest?.();
                          }
                          hide();
                          message.success(success.message);
                    },
                  })
              }
              if(record.accessId !== null && record.sshId !== null && record.sslPath !== null){
                menuItems.push({
                    key: 'buildSsl',
                    label: (
                        <Tooltip placement="topLeft" title="168小时内频繁申请会出问题，我没有做限制，但是letsencrypt不允许">
                          生成并部署Nginx证书
                        </Tooltip>
                    ),
                    onClick: async () => {
                         const hide = message.loading('正在生成证书，这可能需要一些时间...', 0);
                         try{
                            const success = await buildSsl(record.id);;
                            if (success) {
                                actionRef.current?.reloadAndRest?.();
                            }
                            hide();
                            message.success(success.message);
                          } catch (error) {
                            hide();
                        }
                    },
                });
              };

              if(record.accessId !== null){
                menuItems.push({
                    key: 'downloadSsl',
                    label: (
                        <Tooltip placement="topLeft" title="168小时内频繁申请会出问题，我没有做限制，但是letsencrypt不允许">
                          生成并下载Nginx证书
                        </Tooltip>
                    ),
                    onClick: async () => {
                        const hide = message.loading('正在生成证书，这可能需要一些时间...', 0);
                        try {
                            const response = await fetch(apiPrefixDispose('/nginx/ssl/download?id='+record.id), {
                                method: 'GET',
                                headers: {
                                    [process.env.TOKEN_NAME]: localStorage.getItem(process.env.TOKEN_LOCAL_STORAGE_NAME) || ''
                                },
                            });

                            if (!response.ok) {
                                throw new Error(`HTTP error! status: ${response.status}`);
                            }

                            const blob = await response.blob();

                            // 获取文件名
                            const contentDisposition = response.headers.get('Content-Disposition');
                            let filename = `${record.domain}_cert.zip`;
                            if (contentDisposition) {
                                const filenameMatch = contentDisposition.match(/filename="?(.+)"?/i);
                                if (filenameMatch && filenameMatch[1]) {
                                    filename = filenameMatch[1];
                                }
                            }

                            // 创建下载链接并触发下载
                            const url = window.URL.createObjectURL(blob);
                            const a = document.createElement('a');
                            a.style.display = 'none';
                            a.href = url;
                            a.download = filename;
                            document.body.appendChild(a);
                            a.click();
                            window.URL.revokeObjectURL(url);
                            document.body.removeChild(a);

                            hide();
                            message.success('证书下载成功');
                        } catch (error) {
                            hide();
                            message.error('下载失败，请稍后重试');
                            console.error('下载证书时出错:', error);
                        }
                    },
                  });
              }

              return (
                <Dropdown menu={{ items: menuItems }}>
                  <a onClick={(e) => e.preventDefault()}>
                    操作 <DownOutlined />
                  </a>
                </Dropdown>
              );
            },
        },
    ];

    return (
        <PageContainer
            header={{
                title: '',
            }}
        >
            <ProTable<API.Domains>
                headerTitle="查询域名"
                actionRef={actionRef}
                rowKey="id"
                search={{
                    labelWidth: 120,
                }}
                toolBarRender={() => [
                    <Button
                        key="1"
                        type="primary"
                        onClick={() => handleModalVisible(true)}
                    >
                        注册域名
                    </Button>,
                ]}
                pagination={{
                    current, // 当前页码
                    pageSize, // 每页条数
                    showSizeChanger: true, // 是否可以改变 pageSize
                    pageSizeOptions: ['5', '10', '20', '50'], // 自定义每页条数下拉选项
                    onChange: (page, pageSize) => { // 页码或 pageSize 改变的回调。
                      setCurrent(page);
                      setPageSize(pageSize);
                    },
                    onShowSizeChange: (current, size) => {// pageSize 改变的回调。
                      setCurrent(current);
                      setPageSize(size);
                    },
                  }}
                // , sorter, filter
                request={async (params) => {
                    const find: API.DomainPage = {
                        domain: params.domain,
                        page: {
                            pageIndex: params.current,
                            pageSize: params.pageSize,
                        },
                    };
                    const {data, success} = await pageDomain({
                        ...find,
                        // FIXME: remove @ts-ignore
                        // @ts-ignore
                        // sorter,
                        // filter,
                    });
                    return {
                        data: data?.rows || [],
                        total: data?.total,
                        pageSize: data?.pageSize,
                        current: data?.currentPage,
                        success,
                    };
                }}
                columns={columns}
            />
            <CreateForm
                onCancel={() => handleModalVisible(false)}
                modalVisible={createModalVisible}
            >
                <ProTable<API.Domains, API.DomainRegister>
                    onSubmit={async (value) => {
                        const success = await handleRegisterDomain(value);
                        if (success) {
                            handleModalVisible(false);
                            if (actionRef.current) {
                                actionRef.current.reload();
                            }
                        }
                    }}
                    rowKey="id"
                    type="form"
                    columns={columns}
                />
            </CreateForm>
            {stepFormValues && Object.keys(stepFormValues).length ? (
                <SettingWebhook
                    onSubmit={async (value) => {
                        const success = await handleWebhook(value);
                        if (success) {
                        handleWebhookModalVisible(false);
                        setStepFormValues({});
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                        }
                    }}
                    onOpenChange={(visible) => {
                        if (!visible) {
                            handleWebhookModalVisible(false);
                            setStepFormValues({});
                        }
                    }}
                    editModalVisible={webhookModalVisible}
                    values={stepFormValues}
                />
            ) : null}

            {accessFormValues && Object.keys(accessFormValues).length ? (
                <SettingAccess
                    onSubmit={async (value) => {
                        const success = await handleAccess(value);
                        if (success) {
                        handleAccessModalVisible(false);
                        setAccessFormValues({});
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                        }
                    }}
                    onOpenChange={(visible) => {
                        if (!visible) {
                            handleAccessModalVisible(false);
                            setAccessFormValues({});
                        }
                    }}
                    editModalVisible={accessModalVisible}
                    values={accessFormValues}
                />
            ) : null}

            {sshFormValues && Object.keys(sshFormValues).length ? (
                <SettingSSH
                    onSubmit={async (value) => {
                        const success = await handleSsh(value);
                        if (success) {
                        handleSSHModalVisible(false);
                        setSSHFormValues({});
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                        }
                    }}
                    onOpenChange={(visible) => {
                        if (!visible) {
                            handleSSHModalVisible(false);
                            setSSHFormValues({});
                        }
                    }}
                    editModalVisible={sshModalVisible}
                    values={sshFormValues}
                />
            ) : null}

            {sslPathFormValues && Object.keys(sslPathFormValues).length ? (
                <SettingSslPath
                    onSubmit={async (value) => {
                        const success = await handleSslPath(value);
                        if (success) {
                            handleSslPathModalVisible(false);
                            setSslPathFormValues({});
                        if (actionRef.current) {
                            actionRef.current.reload();
                        }
                        }
                    }}
                    onOpenChange={(visible) => {
                        if (!visible) {
                            handleSslPathModalVisible(false);
                            setSslPathFormValues({});
                        }
                    }}
                    editModalVisible={sslPathModalVisible}
                    values={sslPathFormValues}
                />
            ) : null}

        </PageContainer>
    );
};

export default TableList;
